package oop.basicConcept;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;

import static javafx.scene.input.KeyCode.E;
import static javafx.scene.input.KeyCode.T;

/**
 *  1.编程思想：在写代码的方面的一个主导思想(思维方式)
 *    1.1 面向过程
 *        按照事物的发展顺序编写代码
 *        把大象装冰箱拢共分几步
 *    1.2 面向对象
 *        在事物发展的过程中考虑整个事件中都有什么，且都执行了什么操作
 *        把大象装冰箱
 *          大象：进冰箱
 *          冰箱：开门 关门
 *        面向对象中一定有实体，且每个实体都有相应的行为和属性
 *    1.3 两种编程思想的对比
 *        面向过程更符合我们对事物的认知的描述，但是不够灵活
 *        面向过程，改动任何一点，都需要重写代码
 *        面向对象，可以根据实体选择使用的方式
 *  2.类和对象
 *    2.1 类
 *        很多个实体，都有相似的行为和属性，就可以把这些实体抽象出来一个概念，就是类
 *        泛指一个特定的群体，并不是某个具体的事物，是一个抽象的概念
 *    2.2 对象
 *        类的一个具体的实现。万物皆对象
 *        符合这个类别群体中的一个具体的事物
 *  3.使用
 *    必须先创建类，类中可以有特征(属性)和行为(方法)
 *    在主方法中，创建一个类的具体实例(实例化对象)
 *      new 可以执行多次，每次都创建一个实例，多个实例之间相互独立的
 *
 *  4.属性和方法
 *    属性：在类中描述特征的一个变量
 *         与变量不同，变量是在方法中，类中的是属性
 *         使用：实例化对象.属性名 [= xxx]
 *    方法：对于此类中的某个小的事物(冰箱类中的关门动作)定义一个执行过程
 *         语法：
 *           [访问修饰符] 返回值类型 方法名([参数,参数,...]){
 *               执行语句;
 *               [return 返回值;]
 *           }
 *         伪代码：
 *           public 米饭 蒸米饭(米,水){
 *               预热;
 *               吸水;
 *               煮沸;
 *               保温;
 *               return 米饭;
 *           }
 *        java中，判定方法相同的依据有两个：方法名和形参的类型
 *        如果方法名相同而参数不同的话，这样的方法叫做重载(overload)
 *          什么情况是参数不同
 *            类型不同，数量不同，类型不同的参数顺序不同
 *
 *        不定长参数：在不确定参数的个数但确定参数的类型的情况下可以使用不定长参数，本质是一个数组
 *
 *        构造方法 / 构造器(Constructor)
 *          是在new这个类，也就是创建一个实例化对象的同时执行
 *          不可以没有，但可以不写，类本身默认提供一个无参的构造方法，默认使用。
 *          如果定义了有参的构造方法，无参的构造方法必须显示的定义
 *          构造方法是可以重载的
 *          比较适合创建对象的时候对当前对象进行属性的初始化操作
 *
 *        this关键字
 *          使用一个值的时候，多个作用域都提供了同名的变量，此时采取就近原则读取值
 *          如果想不使用就近原则读取属性值
 *            new 出来一个对象，对象.属性
 *            this.属性
 *          this 表示的是当前类的一个实例化对象
 *        创建实例化对象的过程
 *          在堆内存中开辟了一块空间，存储具体的内容
 *          在栈中存对象名(此对象在堆中的地址)
 *
 *  包(package)：
 *    管理类的一个层次，本质就是文件夹
 *    创建类的时候一定要为当前类指定包，否则其他类无法使用
 *      在类的第一行 package xxx.xxx
 *
 *    使用：
 *      在同一个包下的类可以直接调用,不需要import引包
 *      如果不在同一个包下的类，也可以使用，但是需要通过import导入
 *        import 包名.类名 (Ctrl+Shift+O)
 *        import 包名.*
 *
 *  继承：
 *    什么是继承？
 *      子承父业。
 *    父亲与儿子的的属性或行为可以分为几种情况
 *      1.你父亲有的，你也有，是等同关系
 *        只在父类中定义就可以，子类无需定义，可以直接使用父类的此方法或属性
 *      2.你父亲有的，你也有，但是不是等同关系
 *        父类定义属性和方法，子类通过重写的方式重新定义此属性和方法
 *      3.你父亲有的，你没有
 *        实现不了，父类的东西，子类必须继承
 *      4.你父亲没有的，你有
 *        只在子类中定义，父类中不定义
 *    重写
 *      在继承关系下，子类覆盖父类的方法就是重写
 *      子类的方法与父类的方法声明是一致的(方法名和参数都相同)
 *        具体的实现(定义)不同，应该在子类的重写方法上面加 @Override
 *      与重载的区别：
 *    父类与子类的调用
 *      如果创建的是父类的对象，所有的东西都是父类的，此时与子类无关
 *      如果创建的是子类的对象
 *          如果子类中没有的自动使用父类中的
 *          如果子类中重写了父类的方法使用子类的方法
 *          如果子类中定义的而父类中没定义一定使用子类的方法
 *      可以使用 this关键字或super关键字区分是使用当前类对象还是父类对象
 *
 *    特点：
 *      只支持单继承
 *        一个子类只能继承一个父类，但是一个父类可以有多个子类
 *      支持多层继承
 *        继承规则与两层的继承没有区别
 *        
 *    内存结构
 *      在 new 子类 的时候，内存中同时创建了父类和子类多个对象
 *      按照继承的顺序有高到低进行创建
 *      创建子类对象的时候一定找的是父类的无参构造方法
 *      可以使用super()调用其他的构造器，但是必须放在第一行执行，且只能使用一次
 *  多态
 *    原理角度 同一类事物拥有多种不同的表现形式
 *    代码角度 子类的对象使用父类接收
 *
 *    在继承的关系下，子类都拥有父类的行为，但是不同的子类对同一种行为可以有不同的表现形式
 *    不管有多少个子类，也不管有多少种形态，最终子类的行为一定会与父类产生关联
 *
 *    多态执行的方式
 *      父类和子类都有的方法(子类重写父类的方法)，执行子类的方法
 *      父类有的方法，子类没有此方法(默认继承)，执行父类的方法
 *      父类没有的方法，子类新添加的方法(扩展的方法)，无法调用
 *
 *    编译时类型和运行时类型
 *      编译时类型：在编译期确定下来的类型，本质就是定义变量的那个类型，此时可以确定使用哪些方法
 *      运行时类型：运行代码时确定的类，编译期无法确定，看变量后面的字面量的类型
 *
 *    多态中的类型转换
 *      子类转父类(向上转型)
 *        子类对象父类接收本身就是向上转型可以直接使用
 *      父类转子类(向下转型)
 *        可以强制转换，如果直接向下转型有风险的，会报 ClassCastException
 *        解决方案：
 *          先向上转型，再向下转型
 *   封装
 *     信息隐藏，每个类都是封装
 *     方法的封装：
 *
 *     访问修饰符：代表的就是访问的权限
 *       public：公共的
 *       protected：受保护的
 *       默认：
 *       private：私有的
 *
 *          (同包)当前类  同包不同类(包含子类)  不同包子类   不同包非子类
 * private       1          0                 0            0
 * 默认           1          1                 0            0
 * protected     1          1                 1            0
 * public        1          1                 1            1
 *
 *   常用的访问修饰符：public 和 private
 *   在一个类中 一般情况下，属性用private，方法用public
 *
 *   java的访问器 ： getter 和 setter
 *
 *   继承中重写方法的时候，子类的访问修饰符一定要大于等于父类的访问修饰符
 *   子类的返回值类型可以是父类返回值类型的子类
 *
 * final 最终的
 *   原理的角度理解，最后的内容，不会再有其他的内容
 *   可以修饰什么
 *     属性：不可以修改的变量，也就是常量,定义的时候必须给定初始值
 *     方法：不能重写
 *     类：不能被继承
 *     方法里的形参：不能在此方法中修改
 * static 静态的
 *    类里的属性和方法是对象级别的
 *    如果在属性和方法的前面加上static修饰，由对象级别升级为类级别
 *    既然属于类级别，可以通过 类名.属性名/方法名 方式调用属性和方法
 *    在内存中怎么创建
 *      加载类(static的属性和方法) -> 创建对象(对象级别的属性和方法)
 *    加载顺序
 *      类级别的优先于对象级别
 *      父类优先于子类
 *      块优先于构造方法
 *      父类的静态块 -> 子类的静态块 -> 父类的匿名块 -> 父类的构造方法 -> 子类的匿名块 -> 子类的构造方法
 *    静态块和匿名块都可以定义多个，按顺序执行，但是没有意义
 *
 *    static{} 在类加载的时候只能执行一次的方法
 *    静态块与静态方法的区别：静态块只能执行一次，而静态方法可以执行多次
 *
 * 单例模式
 *   设计模式(23种)
 *
 *   单例模式
 *     某些类在解决实际问题的时候，必须只能创建唯一的一个对象。比如太阳
 *     只能从一个类中创建唯一一个对象的模式就是单例模式
 *
 *   创建单例
 *     1.让构造方法是 private
 *     2.在类的内部创建对象
 *     3.当前类中提供一个public的方法把当前类中创建的唯一一个对象给出去
 *
 *   懒汉式：调用多次，每调用一次就会new一遍这个对象,但是内部会做判断，如果实例不为空不再创建新的实例
 *   饿汉式：不管调用多少次，都会返回最开始创建的那个对象。
 */
public class OOP {

    public static void main(String[] args) {

    }


}
